package com.lindroy.androidplayer.logic.network.base.http

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData
import com.lindroy.androidplayer.base.App
import com.lindroy.androidplayer.logic.model.*
import com.lindroy.androidplayer.logic.network.base.BaseResponse

/**
 * @author Lin
 * @date 2021/10/15
 * @function
 */
inline fun <T> LiveData<BaseResponse<T>>.observePageState(
    owner: LifecycleOwner,
    isShowLoading: Boolean = true,
    isShowError: Boolean = true,
    crossinline callback: HttpRequestCallback<T>.() -> Unit
) {
    val requestCallback = HttpRequestCallback<T>().apply(callback)
    observe(owner) {
        when (it) {
            is StartResponse -> {
                if (isShowLoading) {
                    App.eventViewModel.showLoading()
                }
                requestCallback.startCallback?.invoke()
            }
            is SuccessResponse -> requestCallback.successCallback?.invoke(it.data)
            is EmptyResponse -> requestCallback.emptyCallback?.invoke()
            is FailureResponse -> {
                if (isShowError) {
                    App.eventViewModel.showToast(it.exception.errorMsg)
                }
                requestCallback.failureCallback?.invoke(it.exception)
            }
            is CompletionResponse -> {
                if (isShowLoading) {
                    App.eventViewModel.dismissLoading()
                }
                requestCallback.completionCallback?.invoke()
            }
        }
    }
}


inline fun <T> LiveData<BaseResponse<T>>.observeState(
    owner: LifecycleOwner,
    isShowLoading: Boolean = true,
    isShowError: Boolean = true,
    crossinline callback: HttpRequestCallback<T>.() -> Unit
) {
    val requestCallback = HttpRequestCallback<T>().apply(callback)
    observe(owner) {
        when (it) {
            is StartResponse -> {
                if (isShowLoading) {
                    App.eventViewModel.showLoading()
                }
                requestCallback.startCallback?.invoke()
            }
            is SuccessResponse -> requestCallback.successCallback?.invoke(it.data)
            is EmptyResponse -> requestCallback.emptyCallback?.invoke()
            is FailureResponse -> {
                if (isShowError) {
                    App.eventViewModel.showToast(it.exception.errorMsg)
                }
                requestCallback.failureCallback?.invoke(it.exception)
            }
            is CompletionResponse -> {
                if (isShowLoading) {
                    App.eventViewModel.dismissLoading()
                }
                requestCallback.completionCallback?.invoke()
            }
        }
    }
}

inline fun <T> LiveData<BaseResponse<T>>.observeResponse(
    owner: LifecycleOwner,
    isShowLoading: Boolean = true,
    crossinline onStart: OnUnitCallback = {},
    crossinline onEmpty: OnUnitCallback = {},
    crossinline onFailure: OnFailureCallback = { e: RequestException -> },
    crossinline onCompletion: OnUnitCallback = {},
    crossinline onSuccess: OnSuccessCallback<T>
) {
    observe(owner) {
        when (it) {
            is StartResponse -> {
                if (isShowLoading) {
                    App.eventViewModel.showLoading()
                }
                onStart()
            }
            is SuccessResponse -> onSuccess(it.data)
            is EmptyResponse -> onEmpty()
            is FailureResponse -> onFailure(it.exception)
            is CompletionResponse -> {
                if (isShowLoading) {
                    App.eventViewModel.dismissLoading()
                }
                onCompletion()
            }
        }
    }
}

/**
 * 仅监听结果，对请求状态不做处理
 */
inline fun <T> LiveData<BaseResponse<T>>.observeResult(
    owner: LifecycleOwner,
    crossinline callback: HttpRequestCallback<T>.() -> Unit
) {
    val requestCallback = HttpRequestCallback<T>().apply(callback)
    observe(owner) {
        when (it) {
            is StartResponse -> requestCallback.startCallback?.invoke()
            is SuccessResponse -> requestCallback.successCallback?.invoke(it.data)
            is EmptyResponse -> requestCallback.emptyCallback?.invoke()
            is FailureResponse -> requestCallback.failureCallback?.invoke(it.exception)
            is CompletionResponse -> requestCallback.completionCallback?.invoke()
        }
    }
}